package com.example.demo.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.example.demo.mapper.SysAttachinfoMapper;
import com.example.demo.model.entity.SysAttachinfo;
import com.example.demo.model.form.FileInfoForm;
import com.example.demo.service.SysAttachService;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.PostConstruct;
import lombok.Data;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * Aliyun 对象存储服务类
 */
@Component
@ConditionalOnProperty(value = "oss.type", havingValue = "aliyun")
@ConfigurationProperties(prefix = "oss.aliyun")
@Data
public class SysAttachAliyunImplService implements SysAttachService {
    /**
     * 服务Endpoint
     */
    private String endpoint;
    /**
     * 访问凭据
     */
    private String accessKeyId;
    /**
     * 凭据密钥
     */
    private String accessKeySecret;
    /**
     * 存储桶名称
     */
    private String bucketName;

    private OSS aliyunOssClient;
    @Autowired
    private SysAttachinfoMapper sysAttachinfoMapper;

    @PostConstruct
    public void init() {
        aliyunOssClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }

    @Override
    @SneakyThrows
    public FileInfoForm uploadFile(MultipartFile file) {

        // 获取文件名称
        String originalFilename = file.getOriginalFilename();
        // 生成文件名(日期文件夹)
        String suffix = FileUtil.getSuffix(originalFilename);
        String attachGuid = IdUtil.simpleUUID();

        //  try-with-resource 语法糖自动释放流
        try (InputStream inputStream = file.getInputStream()) {

            // 设置上传文件的元信息，例如Content-Type
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(file.getContentType());
            // 创建PutObjectRequest对象，指定Bucket名称、对象名称和输入流
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, attachGuid, inputStream, metadata);
            // 上传文件
            aliyunOssClient.putObject(putObjectRequest);
            int length = inputStream.available();
            // 获取文件访问路径
            String fileUrl = "https://" + bucketName + "." + endpoint + "/" + attachGuid;

            SysAttachinfo attachinfo = new SysAttachinfo();
            attachinfo.setAttachguid(attachGuid);
            attachinfo.setAttachfilename(originalFilename);
            attachinfo.setContenttype(file.getContentType());
            attachinfo.setAttachlength(length);
            attachinfo.setStoragetype("aliyunoss");
            attachinfo.setUpdatetime(new Date());
            attachinfo.setFilepath(fileUrl);
            sysAttachinfoMapper.insert(attachinfo);

            FileInfoForm fileInfo = new FileInfoForm();
            fileInfo.setName(originalFilename);
            fileInfo.setUrl(fileUrl);
            fileInfo.setAttachGuid(attachGuid);
            return fileInfo;
        } catch (Exception e) {
            throw new RuntimeException("文件上传失败");
        }
    }

    @Override
    public boolean deleteFile(String attachGuid) {
        sysAttachinfoMapper.deleteById(attachGuid);
        aliyunOssClient.deleteObject(bucketName, attachGuid);
        return true;
    }

    @Override
    public InputStream downloadFile(String attachGuid) {
        throw new RuntimeException("阿里云不支持下载");
    }

    @Override
    public void updateFileClientinfo(List<String> attachGuidList, String clientGuid) {
        List<SysAttachinfo> attachList = sysAttachinfoMapper.selectListByQuery(QueryWrapper.create().in("attachguid", attachGuidList));
        for (SysAttachinfo attachinfo : attachList) {
            attachinfo.setClientguid(clientGuid);
            sysAttachinfoMapper.update(attachinfo);
        }
    }

    @Override
    public void updateFileClientinfo(List<String> attachGuidList, String clientGuid, String clientTag) {
        List<SysAttachinfo> attachList = sysAttachinfoMapper.selectListByQuery(QueryWrapper.create().in("attachguid", attachGuidList));
        for (SysAttachinfo attachinfo : attachList) {
            attachinfo.setClientguid(clientGuid);
            attachinfo.setClienttag(clientTag);
            sysAttachinfoMapper.update(attachinfo);
        }
    }
}
